﻿using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Reflection;
using System.Security;
using System.Windows.Controls;
using Module.Common.Interface;
using Module.Common.Model;
using Prism.Commands;
using Prism.Modularity;
using Prism.Mvvm;
using Prism.Navigation.Regions;

namespace BomDiffAnalyst.ViewModels;

public class LeftNavigationViewModel : BindableBase
{
    private static LeftNavigationViewModel s_instance;

    private string _message;
    public string Message
    {
        get => _message;
        set => SetProperty(ref _message, value);
    }


    private ObservableCollection<ModuleDescriptor> _dataService = [];
    public ObservableCollection<ModuleDescriptor> DataService
    {
        get => _dataService;
        set => SetProperty(ref _dataService, value);
    }


    public DelegateCommand<SelectionChangedEventArgs> SelectedCommand { get; private set; }

    private ObservableCollection<ModuleDescriptor> _moduleCollection = null;
    private IRegionManager _regionManager;

    public IRegionManager RegionManager
    {
        get { return _regionManager; }
    }
    private IModuleCatalog _moduleCatalog;

    public LeftNavigationViewModel(IRegionManager regionManager,
                                    IModuleCatalog moduleCatalog)

    {


        _regionManager = regionManager;
        _moduleCatalog = moduleCatalog;

        SelectedCommand = new DelegateCommand<SelectionChangedEventArgs>(OnItemSelected);


        #region 获取所有模块信息
        // 将模块目录的模块目录对象转换为具体的 DirectoryModuleCatalog 类型
        DirectoryModuleCatalog directoryCatalog = (DirectoryModuleCatalog)_moduleCatalog;

        // 初始化目录模块目录以加载模块信息
        directoryCatalog.Initialize();

        // 初始化模块集合，用于存储加载的模块描述符
        _moduleCollection = new ObservableCollection<ModuleDescriptor>();

        // 定义一个类型过滤器，用于筛选实现特定接口的类型
        var typeFilter = new TypeFilter(InterfaceFilter);

        // 遍历目录模块目录中的所有模块项
        foreach (var item in directoryCatalog.Items)
        {
            // 将模块项转换为具体的 ModuleInfo 类型
            var moduleInfo = (ModuleInfo)item;

            // 安全加载程序集
            string assemblyPath = new Uri(moduleInfo.Ref).LocalPath;
            var asm = Assembly.LoadFrom(assemblyPath);

            // 遍历程序集中的所有类型
            foreach (var t in asm.GetTypes())
            {
                // 查找类型中实现了指定接口的类型
                var myInterfaces = t.FindInterfaces(typeFilter, typeof(IModuleService).ToString());

                // 如果找到实现了接口的类型
                if (myInterfaces.Length > 0)
                {
                    // 创建接口实现类的实例
                    IModuleService moduleService = (IModuleService)asm.CreateInstance(t.FullName);

                    // 调用接口方法获取模块描述符
                    ModuleDescriptor module = moduleService.getModuleDescriptor();

                    // 将模块描述符添加到模块集合中
                    _moduleCollection.Add(module);
                }
            }
        }

        // 将当前 ViewModel 实例赋值给静态实例属性
        s_instance = this;

        // 将加载的模块集合添加到 DataService 属性中
        s_instance.DataService.AddRange(_moduleCollection);

        #endregion
    }


    private bool InterfaceFilter(Type typeObj, object criteriaObj)
    {
        return typeObj.ToString() == criteriaObj.ToString();
    }


    private void OnItemSelected(SelectionChangedEventArgs e)
    {
        if (e.AddedItems.Count == 0)
        {
            return;
        }

        if (e.AddedItems[0] is ModuleDescriptor item)
        {

            //Clear last module
            foreach (object view in _regionManager.Regions["MainWindow.ModuleContentRegion"].Views)
            {
                _regionManager.Regions["MainWindow.ModuleContentRegion"].Remove(view);
            }

            // register module
            _regionManager.RegisterViewWithRegion("MainWindow.ModuleContentRegion", item.DefaultView);
        }
    }



}
